package com.ruoyi.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.RedissonLockComponent;
import com.ruoyi.common.enums.BusinessEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.PaymentRecord;
import com.ruoyi.system.domain.Product;
import com.ruoyi.system.mapper.PaymentRecordMapper;
import com.ruoyi.system.service.IProductService;
import com.ruoyi.system.domain.vo.AdminPaymentRecordQuerReqVo;
import com.ruoyi.system.domain.vo.AdminPaymentRecordQueryListRes;
import com.ruoyi.web.service.ISysPaymentRecordService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class SysPaymentRecordImpl  extends ServiceImpl<PaymentRecordMapper, PaymentRecord> implements ISysPaymentRecordService {


    @Autowired
    private RedissonLockComponent redissonLockComponent;

    @Autowired
    private IProductService productService;

    @Autowired
    private PaymentRecordMapper paymentRecordMapper;

    @Override
    @Transactional
    public void redeliver(List<Long> ids) {
        List<PaymentRecord> paymentRecords = this.listByIds(ids);
        if (paymentRecords.parallelStream().anyMatch(record -> !"3".equals(record.getPayStatus()))) {
            throw new ServiceException("请选择支付成功单发货失败的记录");
        }

        paymentRecords.forEach(record -> {
            // 使用分布式锁
            Boolean result = redissonLockComponent.execByDistributedLock("update_payment_record:" + record.getId(), 2L, () -> {
                LambdaUpdateWrapper<PaymentRecord> updateWrapper = Wrappers.lambdaUpdate(PaymentRecord.class);
                updateWrapper.eq(PaymentRecord::getId, record.getId())
                        .set(PaymentRecord::getPayStatus, "2")
                        .set(PaymentRecord::getMsg, null);
                Product product = productService.getById(record.getProductId());
                Optional.ofNullable(product).orElseThrow(() -> new ServiceException("存在无效商品：" + record.getProductCnName()));
                if (ObjectUtils.equals(product.getStatus(), 0)) {
                    new ServiceException(record.getProductCnName() + "：已下架");
                }
                Object savePoint = null;
                try {
                    //设置回滚点
                    savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
                    if (BusinessEnum.ProductType.SELLE.getCode().equals(product.getType())) {
                        productService.reduceStock(record.getProductId(), record.getCount(), record.getId());
                    }
                    this.update(updateWrapper);
                    return true;
                } catch (Exception e) {
                    //手工回滚异常
                    TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                    return false;
                }
            });
            if (!result) {
                throw new ServiceException(String.format("商品编号【%s】库存不足，发货失败", record.getProductId()));
            }
        });

    }

    @Override
    public List<AdminPaymentRecordQueryListRes> adminQueryList(Page<AdminPaymentRecordQueryListRes> page, AdminPaymentRecordQuerReqVo adminPaymentRecordQuerReqVo) {
        return paymentRecordMapper.adminQueryList(page, adminPaymentRecordQuerReqVo);
    }
}
